
def be_int(x, k=4):  # bit encode
    l = []
    for i in range(k):
        x, t = divmod(x, 2)
        l.append(t)
    l.reverse()
    return l
    
def bd_int(l):
    acc = 0
    for b in l:
        acc *= 2
        acc += b
    return acc

def popn(l, n):
    acc = l[:n]
    l[:n] = []
    return acc


def b32en(l):     # 简易base32，直接补0，最前面3位表示补0的个数
    chl = 'abcdefghijklmnopqrstuvwxyz234567'
    offset = (-len(l) - 3) % 5
    l = be_int(offset, 3) + l + [0] * offset
    acc = []
    while l:
        assert len(l) >= 5
        nl = popn(l, 5)
        acc.append(chl[bd_int(nl)])
    return ''.join(acc)
    
def b32de(s): 
    chl = 'abcdefghijklmnopqrstuvwxyz234567'
    l = []
    for ch in s:
        l.extend(be_int(chl.index(ch), 5))
    offset = bd_int(popn(l, 3))
    l[-offset:] = []
    return l
    

def en(mat):
    acc = []
    z, y, x = len(mat), len(mat[0]), len(mat[0][0])
    acc.extend(be_int(x))
    acc.extend(be_int(y))
    acc.extend(be_int(z))
    flat = sum(sum(mat, []), [])
    now = -1
    for cell in flat:
        acc.extend(be_int(cell, 1))
    return b32en(acc)


def de(s):
    acc = b32de(s)
    x = bd_int(popn(acc, 4))    # x
    y = bd_int(popn(acc, 4))    # y
    z = bd_int(popn(acc, 4))    # z
    # ~ print("shape", x, y, z)
    flat = []
    while acc:
        cell = bd_int(popn(acc, 1))
        flat.append(cell)
    data = [flat[i: i+x] for i in range(0, len(flat), x)]
    data = [data[i: i+y] for i in range(0, len(data), y)]
    
    return data



if __name__ == "__main__":

    m = [
    [[1, 1], [0, 1]], 
    [[0, 1], [0, 0]],
    [[0, 1], [0, 0]],
    ]

    r = en(m)
    print(r)
    print(de(r))
